-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[libc++] Diagnose passing null pointers to a bunch of APIs #148585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
8fa51be
to
892f584
Compare
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesPatch is 34.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/148585.diff 11 Files Affected:
diff --git a/libcxx/.clang-format b/libcxx/.clang-format
index f372ac9619997..9557b955cd72c 100644
--- a/libcxx/.clang-format
+++ b/libcxx/.clang-format
@@ -33,6 +33,7 @@ AttributeMacros: [
'_LIBCPP_DEPRECATED_IN_CXX20',
'_LIBCPP_DEPRECATED_IN_CXX23',
'_LIBCPP_DEPRECATED',
+ '_LIBCPP_DIAGNOSE_NULLPTR_IF',
'_LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION',
'_LIBCPP_EXPORTED_FROM_ABI',
'_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS',
diff --git a/libcxx/include/__config b/libcxx/include/__config
index d940461c30234..3b3e4cb6f413e 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1095,6 +1095,20 @@ typedef __char32_t char32_t;
# define _LIBCPP_DIAGNOSE_WARNING(...)
# endif
+# if __has_attribute(__diagnose_if__) && !defined(_LIBCPP_APPLE_CLANG_VER) && \
+ (!defined(_LIBCPP_CLANG_VER) || _LIBCPP_CLANG_VER >= 2001)
+# define _LIBCPP_DIAGNOSE_IF(...) __attribute__((__diagnose_if__(__VA_ARGS__)))
+# else
+# define _LIBCPP_DIAGNOSE_IF(...)
+# endif
+
+# define _LIBCPP_DIAGNOSE_NULLPTR_IF(condition, condition_description) \
+ _LIBCPP_DIAGNOSE_IF( \
+ condition, \
+ "null passed to calle that requires a non-null argument" condition_description, \
+ "warning", \
+ "nonnull")
+
# if __has_cpp_attribute(_Clang::__lifetimebound__)
# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
# else
diff --git a/libcxx/include/__memory/construct_at.h b/libcxx/include/__memory/construct_at.h
index b64e64b5a29b0..a59e2f3bd5ea5 100644
--- a/libcxx/include/__memory/construct_at.h
+++ b/libcxx/include/__memory/construct_at.h
@@ -32,8 +32,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
-template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
-_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) {
+template <class _Tp, class... _Args, class = decltype(::new (std::declval<void*>()) _Tp(std::declval<_Args>()...))>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* _LIBCPP_DIAGNOSE_NULLPTR __location, _Args&&... __args) {
_LIBCPP_ASSERT_NON_NULL(__location != nullptr, "null pointer given to construct_at");
return ::new (static_cast<void*>(__location)) _Tp(std::forward<_Args>(__args)...);
}
@@ -73,13 +73,13 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_at(_Tp* __loc) {
#if _LIBCPP_STD_VER >= 17
template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy_at(_Tp* __loc) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy_at(_Tp* _LIBCPP_DIAGNOSE_NULLPTR __loc) {
std::__destroy_at(__loc);
}
# if _LIBCPP_STD_VER >= 20
template <class _Tp, enable_if_t<is_array_v<_Tp>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr void destroy_at(_Tp* __loc) {
+_LIBCPP_HIDE_FROM_ABI constexpr void destroy_at(_Tp* _LIBCPP_DIAGNOSE_NULLPTR __loc) {
std::__destroy_at(__loc);
}
# endif
diff --git a/libcxx/include/print b/libcxx/include/print
index be05d30e0147f..0ff314c22dcd9 100644
--- a/libcxx/include/print
+++ b/libcxx/include/print
@@ -329,7 +329,8 @@ __vprint_unicode([[maybe_unused]] FILE* __stream,
} // namespace __print
template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
+_LIBCPP_HIDE_FROM_ABI void
+print(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, format_string<_Args...> __fmt, _Args&&... __args) {
# if _LIBCPP_HAS_UNICODE
if constexpr (__print::__use_unicode_execution_charset)
__print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
@@ -346,7 +347,8 @@ _LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __arg
}
template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
+_LIBCPP_HIDE_FROM_ABI void
+println(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, format_string<_Args...> __fmt, _Args&&... __args) {
# if _LIBCPP_HAS_UNICODE
// Note the wording in the Standard is inefficient. The output of
// std::format is a std::string which is then copied. This solution
@@ -361,7 +363,7 @@ _LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt
}
template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
-_LIBCPP_HIDE_FROM_ABI inline void println(FILE* __stream) {
+_LIBCPP_HIDE_FROM_ABI inline void println(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream) {
std::print(__stream, "\n");
}
@@ -377,7 +379,8 @@ _LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __a
# if _LIBCPP_HAS_UNICODE
template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
-_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __fmt, format_args __args) {
+_LIBCPP_HIDE_FROM_ABI inline void
+vprint_unicode(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, string_view __fmt, format_args __args) {
__print::__vprint_unicode(__stream, __fmt, __args, false);
}
@@ -389,7 +392,8 @@ _LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args
# endif // _LIBCPP_HAS_UNICODE
template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
-_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args) {
+_LIBCPP_HIDE_FROM_ABI inline void
+vprint_nonunicode(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, string_view __fmt, format_args __args) {
__print::__vprint_nonunicode(__stream, __fmt, __args, false);
}
diff --git a/libcxx/include/string b/libcxx/include/string
index 514dd91c7c172..88c0ed40e3bf7 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1065,13 +1065,15 @@ public:
basic_string(nullptr_t) = delete;
# endif
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n)
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
__init(__s, __n);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero")
: __alloc_(__a) {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
__init(__s, __n);
@@ -1394,7 +1396,8 @@ public:
return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n);
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n)
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero");
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c);
@@ -1521,8 +1524,9 @@ public:
return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s);
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n)
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero");
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c);
template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
@@ -1593,7 +1597,8 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n)
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero");
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c);
_LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c);
@@ -1673,8 +1678,10 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
- replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
+ replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero");
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+ replace(size_type __pos, size_type __n1, const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
@@ -1783,7 +1790,8 @@ public:
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr");
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
@@ -1814,7 +1822,8 @@ public:
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
@@ -1847,7 +1856,8 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
- find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
+ find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
@@ -1881,7 +1891,8 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
- find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
+ find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
@@ -1915,7 +1926,8 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
- find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
+ find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
@@ -1949,7 +1961,8 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
- find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
+ find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
@@ -2026,7 +2039,8 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX20 int
- compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
+ compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero");
// starts_with
@@ -3564,7 +3578,8 @@ operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool
-operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {
+operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+ const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __rhs) _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
using _String = basic_string<_CharT, _Traits, _Allocator>;
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 861187c0640e1..f86b2722aca6c 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -318,8 +318,8 @@ public:
_LIBCPP_HIDE_FROM_ABI basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
- : __data_(__s),
- __size_(__len) {
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__len != 0 && __s == nullptr, " if len is not zero")
+ : __data_(__s), __size_(__len) {
# if _LIBCPP_STD_VER >= 14
// Allocations must fit in `ptrdiff_t` for pointer arithmetic to work. If `__len` exceeds it, the input
// range could not have been valid. Most likely the caller underflowed some arithmetic and inadvertently
@@ -352,7 +352,7 @@ public:
: __data_(ranges::data(__r)), __size_(ranges::size(__r)) {}
# endif // _LIBCPP_STD_VER >= 23
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s)
+ _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s)
: __data_(__s), __size_(std::__char_traits_length_checked<_Traits>(__s)) {}
# if _LIBCPP_STD_VER >= 23
@@ -483,17 +483,19 @@ public:
return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int compare(const _CharT* __s) const _NOEXCEPT {
+ _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
+ compare(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT {
return compare(basic_string_view(__s));
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
- compare(size_type __pos1, size_type __n1, const _CharT* __s) const {
+ compare(size_type __pos1, size_type __n1, const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
return substr(__pos1, __n1).compare(basic_string_view(__s));
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
- compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const {
+ compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero") {
return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
}
@@ -509,13 +511,14 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
- find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
+ find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
- find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
+ find(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find(): received nullptr");
return std::__str_find<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
@@ -534,13 +537,14 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
- rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
+ rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
- rfind(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
+ rfind(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::rfind(): received nullptr");
return std::__str_rfind<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
@@ -560,13 +564,14 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
- find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
+ find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
+ _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
- find_first_of(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
+ find_first_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_of(): received nullptr");
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
@@ -586,13 +591,14 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
- find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT ...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice QOI improvement!
e85b465
to
8ffaa61
Compare
8ffaa61
to
de734de
Compare
Is there a way to suppress this warning while fixing these diagnostic? |
You should be able to use |
…but in this case, it fired just in one file and I had access to the build file of the target it was in, so
It was a true (but boring) positive: https://crbug.com/433273929 |
No description provided.